package wh.coach.domain.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import wh.coach.domain.Project;
import wh.coach.domain.service.ProjectService;
import wh.coach.reposity.mapper.ProjectMapper;

/**
 * @Author xhw
 * @Date 2023/10/27
 * @Version 1.0
 */
@Component
class ProjectServiceImpl implements ProjectService {
    private final ProjectMapper projectMapper;

    public ProjectServiceImpl(ProjectMapper projectMapper) {
        this.projectMapper = projectMapper;
    }

    //获取父节点的path
    private static String getParentPath(String path) {
        if (path == null || path.length() == 0) {
            return null;
        }

        int pos = path.lastIndexOf('.');
        if (pos < 0) {
            return null;
        }

        return path.substring(0, pos);
    }

    @Override
    public List<Project> findAll() {
        List<Project> projects = projectMapper.findAll();
        return buildTree(projects);
    }

    @Override
    public Project findById(Long id) {
        return projectMapper.findById(id);
    }

    // 添加项目
    @Override
    @Transactional
    public void create(Project project) {
        // 先保存项目
        projectMapper.insert(project);

        // 获取生成的项目ID
        Long projectId = project.getId();
        try {
            // 更新项目路径
            if (project.getParentId() != null) {
                Project parent = projectMapper.findById(project.getParentId());
                if (parent != null) {
                    project.setPath(parent.getPath() + "/" + projectId);
                } else {
                    // 处理没有父节点的情况
                    project.setPath("/" + projectId);
                    project.setParentId(0L);
                }
            } else {
                project.setPath("/" + projectId);
            }

            // 更新项目路径信息
            projectMapper.update(project);
        } catch (Exception e) {
            // 发生异常时事务回滚
//            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw e;
        }
    }

    // 删除项目
    //)
    //(要监控系统生成的sql语句 -- 可以用德鲁伊)
    @Override
    public boolean delete(Long id) {

//        String path = idToPath(id);
//        int deletedCount = projectMapper.deleteByPath(path);
//        return deletedCount > 0;

        List<Project> children = projectMapper.findChildrenById(id);
        for (Project child : children) {
            delete(child.getId());
        }
        projectMapper.deleteById(id);


        return true;
    }

    // 获取所有子树
    @Override
    public List<Project> getChildren(final String path) {
        List<Project> projects = projectMapper.findChildrenByPath(path);
        return buildTree(projects);
    }

    // 更新项目信息
    @Override
    public void update(Project project) {
        projectMapper.update(project);
    }

    // 根据路径构建树形结构
    public List<Project> buildTree(List<Project> Projects) {
        // 创建一个空的项目树列表
        List<Project> projectTree = new ArrayList<>();
        // 创建一个空的 ID 列表，用来存储所有项目的 ID
        List<Long> allIds = new ArrayList<>();

        // 遍历原始项目列表
        for (Project Project : Projects) {
            // 将每个项目的 ID 添加到 ID 列表中
            allIds.add(Project.getId());
        }

        // 再次遍历原始项目列表，此次根据父项目 ID 构建树形结构
        for (Project Project : Projects) {
            // 检查当前项目是否为根项目（没有父项目或父项目的 ID 为0）
            if (Project.getParentId() == null || Project.getParentId() == 0 || !allIds.contains(Project.getParentId())) {
                // 如果是根项目，将其添加到项目树中
                projectTree.add(Project);
            } else {
                // 如果不是根项目，调用方法将其添加到对应的父项目下
                addChildToParent(Projects, Project);
            }
        }

        // 返回构建好的项目树
        return projectTree;
    }

    // 将子项目添加到父项目的方法
    private void addChildToParent(List<Project> Projects, Project Project) {
        // 遍历原始项目列表，查找匹配的父项目
        for (Project parent : Projects) {
            // 找到匹配的父项目
            if (parent.getId().equals(Project.getParentId())) {
                // 如果父项目的 children 属性为空，创建一个空的子项目列表
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                // 将当前项目添加为父项目的子项目
                parent.getChildren().add(Project);
                break;
            }
        }
    }

    // 生成项目路径
    private String generatePath(String path) {
        // 获取所有的根节点
        List<Project> roots = projectMapper.findAll();
        // 若无根节点，则说明该项目为根节点
        if (roots.isEmpty()) {
            return "/1";
        }

        // 找到最后一个子节点，获取其路径
        Project lastChild = projectMapper.findLastChild(path);
        String lastChildPath = lastChild.getPath();

        // 生成新的项目路径
        String newPath = incrementPath(lastChildPath);
        return newPath;
    }

    // 将路径中的最后一部分序号加1
    private String incrementPath(String path) {
        String[] parts = path.split("/");
        int lastIndex = parts.length - 1;
        String lastPart = parts[lastIndex];
        int lastNumber = Integer.parseInt(lastPart);

        String incrementedPath = path.substring(0, path.lastIndexOf(lastPart)) + (lastNumber + 1);
        return incrementedPath;
    }

    // 获取子节点所有的兄弟节点
    private List<Project> getSiblings(final String path) {
        return projectMapper.findSiblingsByPath(path);
    }

    // 判断是否为指定路径的子路径
    private boolean isChildPath(String childPath, String parentPath) {
        if (childPath.equals(parentPath)) {
            return false;
        }
        return childPath.startsWith(parentPath + "/");
    }

    // 去除末尾斜杠
    private String getPathWithoutSlash(String path) {
        if (path == null || path.isEmpty()) {
            return path;
        }
        if (path.endsWith("/")) {
            return path.substring(0, path.length() - 1);
        }
        return path;
    }

    // 通过id拿到path
    private String idToPath(Long id) {
        return findById(id).getPath();
    }
}
